#include "sc.h"

#ifdef PSOS
#include "scxtl.h"
extern tmr_t frameTime;
#endif

PixelToPixelOp()
p2p(in stream unsigned char *i,
    out stream unsigned char *o)
{
  *o = 255 - *i;
}

AnisoPixelToPixelOp()
ap2p(in stream unsigned char *i,
     out stream unsigned char *o)
{
  *o = x;
}                    

PixelLookupOp()
pl(in stream unsigned char *i,
   lookup unsigned char l[][],
   out stream unsigned char *o)
{
  *o = l[255-*i][255-*i];
}              

PixelFilterOp()
pf(in stream unsigned char *i,
   out stream unsigned char *o)
{
  *o = *i;

  if (*i > 128)
    push();
}              

PixelToGlobalOp(in int *width=scint(1024),
                in int *height=scint(1024))
p2g(in stream unsigned char *i,
    out stream unsigned char **o)
{
  o[*i][*i] = *i;
}    

LUTNeighbourhoodToPixelOp(in int *lutsize)
lutnbh(in stream unsigned char *i,
       out stream unsigned char *o)
{
  int x, y;
  
  for (y=-*lutsize/2; y <= *lutsize/2; y++)
    for (x=-*lutsize/2; x <= *lutsize/2; x++)
      setLUT(x, y, 1.0/(*lutsize**lutsize));
}

NeighbourhoodToPixelOp()
nbh(in stream unsigned char i[-1..0][-1..0],
    out stream unsigned char *o)
{
  *o = i[-1][0]*0.24 + i[-1][-1]*0.24 + i[0][-1]*0.24 + i[0][0]*0.24;
}

RecursiveNeighbourhoodToPixelOp()
recnbh(in stream unsigned char i[0][0],
       out stream unsigned char o[-1..0][-1..0])
{
  o[0][0] = MAX(i[0][0], MAX(o[-1][0], o[0][-1]));
}

ReductionOp()
red(in stream unsigned char *i,
    in int *p,
    out int *o)
{
  *o = MAX(*i, *p);
}  

OptStackOp2(in stream unsigned char *_init, in int *_threshold)
st(in stream unsigned char i[-1..1][-1..1],
   out stream unsigned char *o)
{
  *o = i[-1][0]*0.24 + i[-1][-1]*0.24 + i[0][-1]*0.24 + i[0][0]*0.24;
}

int MAIN(int argc, char **argv)
{
  STREAM a, b;
  unsigned char c;

  scInit(argc, argv);

  read(scint(0), &a);
  PixelToPixelOp(p2p, &a, &a);
  write(&a, scint(0));

  read(scint(0), &a);
  AnisoPixelToPixelOp(ap2p, &a, &a);
  write(&a, scint(1));

  read(scint(0), &a);
  generate(scint(1024), &b);
  AnisoPixelToPixelOp(ap2p, &b, &b);
  PixelLookupOp(pl, &a, &b, &a);
  write(&a, scint(2));

  read(scint(0), &a);
  PixelFilterOp(pf, &a, &a);
  write(&a, scint(3));

  read(scint(0), &a);
  PixelToGlobalOp(p2g, &a, &a);
  write(&a, scint(4));

  read(scint(0), &a);
  LUTNeighbourhoodToPixelOp(scint(3), lutnbh, &a, &a);
  write(&a, scint(5));

  read(scint(0), &a);
  NeighbourhoodToPixelOp(nbh, &a, &a);
  write(&a, scint(6));

  read(scint(0), &a);
  RecursiveNeighbourhoodToPixelOp(recnbh, &a, &a);
  write(&a, scint(7));

  read(scint(0), &a);
  c = 0;
  ReductionOp(red, &a, &c, &c);
  _block(&c);
  printf("%d\n", c);
  
  read(scint(0), &a);
  generate(scint(1024), &b);
  p2p(&b, &b);
  OptStackOp2(&b, scint(0), st, &a, &a);
  write(&a, scint(9));

  return scExit();
}
